package file.io.readfile;

import java.io.*;

public class FileInputStreamTest {

    public static void main(String[] args) throws Exception {
//        testInputStream();
//        testInputStream2();
        testInputStream3();
//        testInputStreamReader();
    }

    public static void testInputStream() throws Exception {
        String path = "E:\\liyuan-gitee\\my-java-project\\myproj\\data\\file\\test1.txt";

        long length = new File(path).length();
        byte[] buffer = new byte[(int)length];

        FileInputStream fileInputStream = new FileInputStream(path);
        int unread = (int)length;
        //  如果是大文件，需要多次读，这里简单地一次读取文件全部内容
        // 多次读取可以采用的方式:
        // 分配一个大内存，每次读取通过指定偏移以及读取数据大小来移动偏移
        // 全部数据使用一个大内存，分配一个小内存来存储每次读取的数据，然后把每次读取的数据复制到大内存
        try (BufferedInputStream bf = new BufferedInputStream(fileInputStream)) {
            bf.read(buffer, 0, unread);
        }

        System.out.println(new String(buffer));
    }

    public static void testInputStream2() throws Exception {
        String path = "D:\\liyuan-gitee\\my-java-project\\myproj\\data\\file\\test1.txt";

        long length = new File(path).length();
        byte[] buffer = new byte[(int)length];

        FileInputStream fileInputStream = new FileInputStream(path);
        int unread = (int)length;
        //  如果是大文件，需要多次读，这里简单地一次读取文件全部内容
        // 多次读取可以采用的方式:
        // 分配一个大内存，每次读取通过指定偏移以及读取数据大小来移动偏移
        // 全部数据使用一个大内存，分配一个小内存来存储每次读取的数据，然后把每次读取的数据复制到大内存
        int n;
        int pos = 0;
        try (BufferedInputStream bf = new BufferedInputStream(fileInputStream)) {
            while((n = bf.read(buffer, pos, unread)) > 0) {
                pos += n;
                unread = unread - n;
            }
        }

        System.out.println(new String(buffer));
    }

    public static void testInputStream3() throws Exception {
        String path = "D:\\liyuan-gitee\\my-java-project\\myproj\\data\\file\\test1.txt";

        long length = new File(path).length();
        byte[] buffer = new byte[(int)length];

        FileInputStream fileInputStream = new FileInputStream(path);
        int unread = (int)length;
        //  如果是大文件，需要多次读，这里简单地一次读取文件全部内容
        // 多次读取可以采用的方式:
        // 分配一个大内存，每次读取通过指定偏移以及读取数据大小来移动偏移
        // 全部数据使用一个大内存，分配一个小内存来存储每次读取的数据，然后把每次读取的数据复制到大内存
        int n;
        int pos = 0;

        byte[] readBuf = new byte[1024];
        try (BufferedInputStream bf = new BufferedInputStream(fileInputStream)) {
            while((n = bf.read(readBuf)) > 0) {
                int size = Math.min(n, unread);
                System.arraycopy(readBuf, 0, buffer, pos, size);
                pos += n;
                unread = unread - n;
                // 考虑文件增大，比刚开始大小大的情况。
                if (unread <= 0) {
                    break;
                }
            }
        }

        System.out.println(new String(buffer));
    }

    /**
     * 使用字符流
     * @throws Exception
     */
    public static void testInputStreamReader() throws Exception {
        String path = "E:\\liyuan-gitee\\my-java-project\\myproj\\data\\file\\test1.txt";

        long length = new File(path).length();
        byte[] buffer = new byte[(int)length];

        FileInputStream fileInputStream = new FileInputStream(path);
        int unread = (int)length;
        //  按行读取，读到的每一行不包括末尾的换行符
        try (BufferedReader bf = new BufferedReader(new InputStreamReader(fileInputStream))) {
            String line;
            while ((line = bf.readLine()) != null) {
                System.out.println(line);
            }
        }

        System.out.println(new String(buffer));
    }

}
